﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using System.Linq.Expressions;
using System.Web;

namespace LegacyMusic.Data.Repositories
{
    public interface ISongRepository
    {
        //GET
        List<Song> GetAllSongs();
        List<Song> GetAllSongsOrderedAsc(Expression<Func<Song, bool>> orderBy);
        List<Song> GetAllSongsOrderedDesc(Expression<Func<Song, bool>> orderBy);
        IQueryable<Song> GetSpecificSongs(Expression<Func<Song, bool>> where);
        IQueryable<Song> GetSpecificSongsAsc(Expression<Func<Song, bool>> where, Expression<Func<Song, bool>> orderBy);
        IQueryable<Song> GetSpecificSongsDesc(Expression<Func<Song, bool>> where, Expression<Func<Song, bool>> orderBy);

        //ADD
        void AddSong(string title, Guid userId);
        void AddSong(string album, string artists, string beatPerMinute, string bitRate, string fileName, string genre, string itemType, string length, int? rating, string size, string title, Guid userId, int? year);

        //DELETE
        void DeleteSong(Song song);
        void DeleteSong(Guid songId);
    }

    public class SongRepository : ISongRepository
    {
        private readonly LegacyMusicEntities _entities = new LegacyMusicEntities();

        //GET

        public List<Song> GetAllSongs()
        {
            return _entities.Songs.ToList();
        }

        public List<Song> GetAllSongsOrderedAsc(Expression<Func<Song, bool>> orderBy)
        {
            return _entities.Songs.OrderBy(orderBy).ToList();
        }

        public List<Song> GetAllSongsOrderedDesc(Expression<Func<Song, bool>> orderBy)
        {
            return _entities.Songs.OrderByDescending(orderBy).ToList();
        }

        public IQueryable<Song> GetSpecificSongs(Expression<Func<Song, bool>> where)
        {
            return _entities.Songs.Where(where);
        }

        public IQueryable<Song> GetSpecificSongsAsc(Expression<Func<Song, bool>> where, Expression<Func<Song, bool>> orderBy)
        {
            return _entities.Songs.Where(where).OrderBy(orderBy);
        }

        public IQueryable<Song> GetSpecificSongsDesc(Expression<Func<Song, bool>> where, Expression<Func<Song, bool>> orderBy)
        {
            return _entities.Songs.Where(where).OrderByDescending(orderBy);
        }


        //ADD

        private void AddSong(Song newSong)
        {
            try
            {
                _entities.AddToSongs(newSong);
                _entities.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("An error occured while saving the new song. The error was : {0}", ex.Message));
            }
        }

        public void AddSong(string title, Guid userId)
        {
            if (string.IsNullOrWhiteSpace(title) || userId == Guid.Empty)
            {
                throw new Exception("You must set the title and userId to save a new song.");
            }

            AddSong(Song.CreateSong(Guid.NewGuid(), title, DateTime.Now, userId));
        }

        public void AddSong(string album, string artists, string beatPerMinute, string bitRate, string fileName, string genre, string itemType, string length, int? rating, string size, string title, Guid userId, int? year)
        {
            if (string.IsNullOrWhiteSpace(title) || userId == Guid.Empty)
            {
                throw new Exception("You must set the title and userId to save a new song.");
            }

            var song = new Song
                           {
                               SongId = Guid.NewGuid(),
                               CreatedOn = DateTime.Now,
                               DeletedOn = null,
                               Title = title,
                               UserId = userId,
                               Album = album,
                               Artists = artists,
                               BeatPerMinute = beatPerMinute,
                               BitRate = bitRate,
                               FileName = fileName,
                               Genre = genre,
                               ItemType = itemType,
                               Length = length,
                               Rating = rating,
                               Size = size,
                               Year = year
                           };

            AddSong(song);
        }


        //DELETE

        public void DeleteSong(Song song)
        {
            try
            {
                _entities.DeleteObject(song);
                _entities.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("An error occured while deleting a song. The error was : {0}", ex.Message));
            }
        }

        public void DeleteSong(Guid songId)
        {
            var song = _entities.Songs.FirstOrDefault(p => p.SongId == songId);
            if (song != null)
            {
                DeleteSong(song);
            }
        }
    }
}